﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.ComponentModel;
using Water.Web.Controls.BaseInterface;
using Water.Web.JSON;
using System.Web.UI.Design;
using System.Drawing.Design;
using System.Drawing;

//[assembly: WebResource("Water.Resources.Default.JS.Autocomplete.jquery.autocomplete.pack.js", "text/javascript")]
[assembly: WebResource("Water.Resources.Default.JS.Autocomplete.jquery.autocomplete.js", "text/javascript")]
[assembly: WebResource("Water.Resources.Default.JS.Autocomplete.jquery.autocomplete.help.js", "text/javascript")]
[assembly: WebResource("Water.Resources.Default.JS.Dialog.Dialog.js", "text/javascript")]
namespace Water.Web.Controls
{
    [ToolboxData("<{0}:Autocomplete runat=server></{0}:Autocomplete>")]
    public class Autocomplete :BaseTextBox,INamingContainer
    {
        //private Water.Web.Controls.BaseInterface.BaseTextBox input_display;
        private System.Web.UI.WebControls.HiddenField input_value;

        private const string DEFAULTURL = "/App_Foundtion/Autocomplete/Autocomplete.ashx";

        protected override void CreateChildControls()
        {
            input_value = new HiddenField();
            this.input_value.ID = "value";
            this.Controls.Add(input_value);
        }

        /*如果仅需要依次呈现控件 仅仅override CreateChildControls即可,如果需要进行布局控制override RenderContents*/

        public override void RenderBeginTag(HtmlTextWriter writer)
        {
            base.RenderBeginTag(writer);
            if (!DesignMode)
                this.input_value.RenderControl(writer);
        }

        protected override void AddAttributesToRender(HtmlTextWriter writer)
        {
            base.AddAttributesToRender(writer);
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            this.TokenCssClass = "field_token_autocomplete";
        }

        protected override void OnLoad(EventArgs e)
        {
            this.CreateJS();
            base.OnLoad(e);
            this.Page.ClientScript.RegisterClientScriptResource(typeof(Autocomplete), "Water.Resources.Default.JS.Autocomplete.jquery.autocomplete.js");
            this.Page.ClientScript.RegisterClientScriptResource(typeof(Autocomplete), "Water.Resources.Default.JS.Autocomplete.jquery.autocomplete.help.js");
            PageManager.RegisterPageStyleSheet(this, "Autocomplete_css", "CSS/jquery.autocomplete.css");
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            
            if(!string.IsNullOrEmpty(this.UpdateJS))
                this.Page.ClientScript.RegisterStartupScript(typeof(Autocomplete), this.UniqueID, this.UpdateJS, true);

            string js;
            if (string.IsNullOrEmpty(this.Src) && !string.IsNullOrEmpty(this.DialogId))
            {
                this.TokenCssClass = "field_token_dot";
                this.Page.ClientScript.RegisterClientScriptResource(typeof(Dialog), "Water.Resources.Default.JS.Dialog.Dialog.js");
                js = @"$j(function() {$j('#" + this.ClientID + "_token').click(function(){$j('#" + Util.Utils.FindControlEx(this.DialogId, this.Page).ClientID + "').showDialog('" + this.ClientID + "_token',1);});});";
                this.Page.ClientScript.RegisterStartupScript(typeof(SearchBox), this.UniqueID, js, true);
            }
            else if (!string.IsNullOrEmpty(this.Src))
            {
                this.TokenCssClass = "field_token_dot";
                this.Page.ClientScript.RegisterClientScriptResource(typeof(Dialog), "Water.Resources.Default.JS.Dialog.Dialog.js");
                js = @"$j(function() {$j('#" + this.ClientID + "_token').click(function(){$j(this).open('" + this.Src + "'," + toDialogKeyValue() + ",'" + this.input_value.ClientID + "','" + this.ClientID + "',1);});});";
                this.Page.ClientScript.RegisterStartupScript(typeof(SearchBox), this.UniqueID, js, true);
            }

        }

        private void CreateJS()
        {
            string js = string.Empty;
            if (!string.IsNullOrEmpty(this.Data))
            {
                js = "$j(function(){$j('#" + this.ClientID + "').autocomplete(" + this.Data + "," + toKeyValue() + ");})\n";
            }
            else if (string.IsNullOrEmpty(this.AjaxMethodName))
            {
                if (this.OnceForever)
                {
                    if (!ht.Contains("formatItem"))
                        ht.Add("formatItem", this.FormatItem);
                    string autoSettings = toKeyValue();
                    js = "$j(function(){$j('#" + this.ClientID + "').autoCompleteOnce('" + this.Url + "'," + autoSettings + ");});\n";
                }
                else
                {
                    if (!ht.Contains("formatItem"))
                        ht.Add("formatItem", this.FormatItem);
                    string autoSettings = toKeyValue();
                    js = "$j(function(){$j('#" + this.ClientID + "').autocomplete('" + this.Url + "'," + autoSettings + ");});\n";
                }
            }
            else
            {
                if (this.OnceForever)
                {
                    string setting = "{url:'" + this.Url + "',"
                                                          + "ajaxMethodName:'" + this.AjaxMethodName + "',"
                                                          + "returnType:" + (int)this.ReturnType + ","
                                                          + "parameters:[" + this.Parameters + "]"
                                                          + "}";
                    string autoSettings = toKeyValue();
                    js = "$j(function(){$j('#" + this.ClientID + "').autoCompleteOnce(" + setting + "," + autoSettings + ",null);});\n";
                }
                else
                {
                    if (!ht.Contains("formatItem"))
                        ht.Add("formatItem", this.FormatItem);
                    string fun_url = "$j.autoCompleteUrl(" + "{url:'" + this.Url + "',"
                                                          + "ajaxMethodName:'" + this.AjaxMethodName + "',"
                                                          + "returnType:" + (int)this.ReturnType + ","
                                                          + "parameters:[" + this.Parameters + "]"
                                                          + "})";
                    js = "$j(function(){$j('#" + this.ClientID + "').autocomplete(" + fun_url + "," + toKeyValue() + ");});\n";
                }
            }
            if (!string.IsNullOrEmpty(js))
                this.UpdateJS = js;
        }

        [Bindable(true, BindingDirection.TwoWay), Localizable(true), Category("Appearance"), DefaultValue(""), GlobalizeDescription("Value")]
        public override string Value
        {
            get
            {
                return this.input_value.Value;
            }
            set
            {
                EnsureChildControls();
                this.input_value.Value = value;
            }
        }

        private Hashtable ht = new Hashtable();
        private Hashtable ht_dialog = new Hashtable();

        private string data;

        [Browsable(true), Category("Behavior"), GlobalizeDescription("Data")]
        public string Data
        {
            get { return data; }
            set { data = value; }
        }

        private string typeName;
        [Browsable(true), Category("Behavior"), GlobalizeDescription("TypeName")]
        public string TypeName
        {
            get { return typeName; }
            set { typeName = value; }
        }

        private string url;
        [Browsable(true), Category("Behavior"), GlobalizeDescription("Url")]
        public string Url
        {
            get 
            {
                if (string.IsNullOrEmpty(this.url))
                {
                    string _appPath = this.Page.Request.ApplicationPath;
                    if (_appPath.EndsWith("/"))
                    {
                        _appPath = _appPath.Substring(0, _appPath.Length - 1);
                    }
                    string _url = _appPath
                        + Autocomplete.DEFAULTURL
                        + "?TypeName=" + this.typeName
                        + "&MatchField=" + this.MatchField
                        + "&MatchCase=" + this.MatchCase
                        + "&MethodName=" + this.MethodName;
                    return _url;
                }
                return url; 
            }
            set { url = value; }
        }

        private string matchField;
        [Browsable(true), Category("Behavior"), GlobalizeDescription("MatchField")]
        public string MatchField
        {
            get { return matchField; }
            set { matchField = value; JSONSettingUtil.SetHashtable(ht, "matchField", "'" + value.ToUpper() + "'"); }
        }

        private string returnValueField;
        [Browsable(true), Category("Behavior"), GlobalizeDescription("ReturnValueField")]
        public string ReturnValueField
        {
            get { return returnValueField.ToUpper(); }
            set { returnValueField = value; JSONSettingUtil.SetHashtable(ht, "returnValueField", "'" + value.ToUpper() + "'"); }
        }

        private string returnTextField;
        [Browsable(true), Category("Behavior"), GlobalizeDescription("ReturnTextField")]
        public string ReturnTextField
        {
            get { return returnTextField.ToUpper(); }
            set { returnTextField = value; JSONSettingUtil.SetHashtable(ht, "returnTextField", "'" + value.ToUpper() + "'"); }
        }


        private string ajaxMethodName;

        [Browsable(true), Category("Behavior"), GlobalizeDescription("AjaxMethodName")]
        public string AjaxMethodName
        {
            get { return ajaxMethodName; }
            set { ajaxMethodName = value; }
        }

        private string methodName;

        [Browsable(true), Category("Behavior"), GlobalizeDescription("MethodName")]
        public string MethodName
        {
            get { return methodName; }
            set { methodName = value; }
        }
        private ReturnType returnType = ReturnType.JSONInArray;

        [Browsable(true), Category("Behavior"), GlobalizeDescription("ReturnType"), DefaultValue(ReturnType.JSONInArray)]
        public ReturnType ReturnType
        {
            get { return returnType; }
            set { returnType = value; }
        }

        private string formatItem;
        [Browsable(true), Category("Behavior"), GlobalizeDescription("FormatItem"),Editor("Water.Web.Controls.Design.RichTextEditor",typeof(UITypeEditor))]
        public string FormatItem
        {
            get
            {
                if (string.IsNullOrEmpty(formatItem))
                {
                    string f_item = @"function aa(row,i,max) {"
                            + @" return '<td>'+row."+this.ReturnTextField+"+'</td><td>'+row."+this.ReturnValueField+"+'</td><td class=ac_index>'+i+'/'+max+'</td>';"
                            + "}";
                    return f_item; 
                }
                return formatItem; 
            }
            set { formatItem = value; JSONSettingUtil.SetHashtable(ht, "formatItem", value); }
        }

        private string formatMatch;
        [Browsable(true), Category("Behavior"), GlobalizeDescription("FormatMatch"), Editor("Water.Web.Controls.Design.RichTextEditor", typeof(UITypeEditor))]
        public string FormatMatch
        {
            get { return formatMatch; }
            set { formatMatch = value; JSONSettingUtil.SetHashtable(ht, "formatMatch", value); }
        }

        private string formatResult;
        [Browsable(true), Category("Behavior"), GlobalizeDescription("FormatResult"), Editor("Water.Web.Controls.Design.RichTextEditor", typeof(UITypeEditor))]
        public string FormatResult
        {
            get { return formatResult; }
            set { formatResult = value; JSONSettingUtil.SetHashtable(ht, "formatResult", value); }
        }

        private string formatValue;
        [Browsable(true), Category("Behavior"), GlobalizeDescription("FormatValue"), Editor("Water.Web.Controls.Design.RichTextEditor", typeof(UITypeEditor))]
        public string FormatValue
        {
            get { return formatValue; }
            set { formatValue = value; JSONSettingUtil.SetHashtable(ht, "FormatValue", value); }
        }

        private int minChars = 1;

        [Browsable(true), Category("Behavior"), GlobalizeDescription("MinChars"), DefaultValue(1)]
        public int MinChars
        {
            get { return minChars; }
            set { minChars = value; JSONSettingUtil.SetHashtable(ht, "minChars", value); }
        }
        private int delay;

        [Browsable(true), Category("Behavior"), GlobalizeDescription("Delay")]
        public int Delay
        {
            get { return delay; }
            set { delay = value; JSONSettingUtil.SetHashtable(ht, "delay", value); }
        }

        private int cacheLength = 10;

        [Browsable(true), Category("Behavior"), GlobalizeDescription("CacheLength"), DefaultValue(10)]
        public int CacheLength
        {
            get { return cacheLength; }
            set { cacheLength = value; JSONSettingUtil.SetHashtable(ht, "cacheLength", value); }
        }

        private bool matchSubset = true;

        [Browsable(true), Category("Behavior"), GlobalizeDescription("MatchSubset"), DefaultValue(true)]
        public bool MatchSubset
        {
            get { return matchSubset; }
            set { matchSubset = value; JSONSettingUtil.SetHashtable(ht, "matchSubset", value); }
        }
        private bool matchCase = false;

        [Browsable(true), Category("Behavior"), GlobalizeDescription("MatchCase"), DefaultValue(false)]
        public bool MatchCase
        {
            get { return matchCase; }
            set { matchCase = value; JSONSettingUtil.SetHashtable(ht, "matchCase", value); }
        }
        private bool matchContains = false;

        [Browsable(true), Category("Behavior"), GlobalizeDescription("MatchContains"), DefaultValue(false)]
        public bool MatchContains
        {
            get { return matchContains; }
            set { matchContains = value; JSONSettingUtil.SetHashtable(ht, "matchContains", value); }
        }
        private bool mustMatch = true;

        [Browsable(true), Category("Behavior"), GlobalizeDescription("MustMatch"), DefaultValue(false)]
        public bool MustMatch
        {
            get { return mustMatch; }
            set { mustMatch = value; JSONSettingUtil.SetHashtable(ht, "mustMatch", value); }
        }
        private bool selectFirst = true;

        [Browsable(true), Category("Behavior"), GlobalizeDescription("selectFirst"), DefaultValue(true)]
        public bool SelectFirst
        {
            get { return selectFirst; }
            set { selectFirst = value; JSONSettingUtil.SetHashtable(ht, "selectFirst", value); }
        }
        private string extraParams;

        [Browsable(true), Category("Behavior"), GlobalizeDescription("ExtraParams")]
        public string ExtraParams
        {
            get { return extraParams; }
            set { extraParams = value; JSONSettingUtil.SetHashtable(ht, "extraParams", value); }
        }
        private bool multiple = false;

        [Browsable(true), Category("Behavior"), GlobalizeDescription("Multiple"), DefaultValue(false)]
        public bool Multiple
        {
            get { return multiple; }
            set { multiple = value; JSONSettingUtil.SetHashtable(ht, "multiple", value); }
        }
        private string multipleSeparator = ",";

        [Browsable(true), Category("Behavior"), GlobalizeDescription("MultipleSeparator"), DefaultValue(",")]
        public string MultipleSeparator
        {
            get { return multipleSeparator; }
            set { multipleSeparator = value; JSONSettingUtil.SetHashtable(ht, "multipleSeparator", value); }
        }
        private bool autoFill = false;

        [Browsable(true), Category("Behavior"), GlobalizeDescription("AutoFill"), DefaultValue(false)]
        public bool AutoFill
        {
            get { return autoFill; }
            set { autoFill = value; JSONSettingUtil.SetHashtable(ht, "autoFill", value); }
        }
        private int max = 10;

        [Browsable(true), Category("Behavior"), GlobalizeDescription("Max"), DefaultValue(10)]
        public int Max
        {
            get { return max; }
            set { max = value; JSONSettingUtil.SetHashtable(ht, "max", value); }
        }
        private string highlight;

        [Browsable(true), Category("Behavior"), GlobalizeDescription("Highlight")]
        public string Highlight
        {
            get { return highlight; }
            set { highlight = value; JSONSettingUtil.SetHashtable(ht, "highlight", value); }
        }
        private bool scroll = true;

        [Browsable(true), Category("Behavior"), GlobalizeDescription("Scroll"), DefaultValue(false)]
        public bool Scroll
        {
            get { return scroll; }
            set { scroll = value; JSONSettingUtil.SetHashtable(ht, "scroll", value); }
        }
        private int selectHeight = 180;

        [Browsable(true), Category("Behavior"), GlobalizeDescription("ScrollHeight"), DefaultValue(180)]
        public int SelectHeight
        {
            get { return selectHeight; }
            set { selectHeight = value; JSONSettingUtil.SetHashtable(ht, "scrollHeight", value); }
        }

        private int selectWidth = 180;

        [Browsable(true), Category("Behavior"), GlobalizeDescription("Width"), DefaultValue(180)]
        public int SelectWidth
        {
            get { return selectWidth; }
            set { selectWidth = value; JSONSettingUtil.SetHashtable(ht, "width", value); }
        }


        private string parse;

        [Browsable(true), Category("Behavior"), GlobalizeDescription("Parse")]
        public string Parse
        {
            get {
                if (string.IsNullOrEmpty(this.parse))
                {
                    string parser = "function parser(data) {"
                       + "return $.map(eval(data), function(row) {"
                       + " return {"
                       + "data: row,"
                       + "value:row." + this.ReturnValueField + ","
                       + "result:row."+this.ReturnTextField
                       + "}"
                       + "});"
                       + "}";
                    return parser;
                }
                return parse; 
            }
            set { parse = value; JSONSettingUtil.SetHashtable(ht, "parse", value); }
        }

        private string otherSetting;

        [Browsable(true), Category("Behavior"), GlobalizeDescription("OtherSetting")]
        public string OtherSetting
        {
            get { return otherSetting; }
            set { otherSetting = value; }
        }

        private bool onceForever = false;

        [Browsable(true), Category("Behavior"), GlobalizeDescription("OnceForever"),DefaultValue(false)]
        public bool OnceForever
        {
            get { return onceForever; }
            set { onceForever = value; }
        }

        private string parameters;
        [Browsable(true), Category("Behavior"), GlobalizeDescription("Parameters")]
        public string Parameters
        {
            get { return parameters; }
            set { parameters = value;}
        }


        private string toKeyValue()
        {
            string strReturn = "";
            strReturn = JSONSettingUtil.ToKeyValue(ht);
            if (!string.IsNullOrEmpty(this.OtherSetting))
                strReturn += "," + this.OtherSetting;
            return "{" + strReturn + "}";
        }
        private string toDialogKeyValue()
        {
            string strReturn = "";
            strReturn = JSONSettingUtil.ToKeyValue(ht_dialog);
            if (!string.IsNullOrEmpty(this.OtherSetting))
                strReturn += "," + this.OtherSetting;
            return "{" + strReturn + "}";
        }


        #region dialog
        private string dialogId;

        [Browsable(true), GlobalizeDescription("DialogId"), Category("Behavior")]
        public string DialogId
        {
            get { return dialogId; }
            set { dialogId = value; }
        }
        private string src;

        [Browsable(true), GlobalizeDescription("Src"), Category("Behavior"), Editor("System.Web.UI.Design.UrlEditor", typeof(UITypeEditor))]
        public string Src
        {
            get { return src; }
            set { src = value; }
        }

        private int dialogWidth;
        [GlobalizeDescription("DialogWidth"), Category("Layout")]
        public virtual int DialogWidth
        {
            get
            {
                return this.dialogWidth;
            }
            set
            {
                this.dialogWidth = value;
                JSONSettingUtil.SetHashtable(ht_dialog, "width", value.ToString());
            }
        }

        private int dialogHeight;
        [GlobalizeDescription("DialogHeight"), Category("Layout")]
        public virtual int DialogHeight
        {
            get
            {
                return this.dialogHeight;
            }
            set
            {
                this.dialogHeight = value;
                JSONSettingUtil.SetHashtable(ht_dialog, "height", value);
            }
        }
        #endregion
    }
}
